var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import path from "path";
import fs from "fs";
import { jsPDF } from "jspdf";
import "./heiti-normal.js";
import XLSX from "xlsx";
import { parse } from "smol-toml";
const INPUT_PROFILE = process.argv[2];
const INPUT_FILE = process.argv[3];
function main() {
    return __awaiter(this, void 0, void 0, function* () {
        usage();
        const config = readTomlConfig("config.toml");
        const profile = config[INPUT_PROFILE];
        showProfile(profile);
        const contents = readXlsx(INPUT_FILE);
        console.log("f", contents);
        drawLabels(profile, contents, "res.pdf", true);
        console.log("Done");
    });
}
main();
function usage() {
    console.log(`
npm run dev <profile> <xlsx_file>
    `);
}
function readTomlConfig(filePath) {
    const content = fs.readFileSync(filePath, "utf8");
    return parse(content);
}
function readXlsx(filePath) {
    const wb = XLSX.readFile(filePath);
    const ws = wb.Sheets[wb.SheetNames[0]];
    return XLSX.utils.sheet_to_json(ws, { header: 1 });
}
function drawLabels(profile, contents, filePath, withBorder = false) {
    var _a;
    const { paper_size, label_size, gap, zero_point } = profile;
    const { row, col } = calcMaxRowCol(paper_size, label_size, gap, zero_point);
    const orientation = paper_size.w > paper_size.h ? "landscape" : "portrait";
    const pdf = new jsPDF({
        orientation: orientation, // 方向要根据纸张尺寸设置，这里是横向
        unit: "mm",
        format: [paper_size.w, paper_size.h],
    });
    const myFont = fs.readFileSync("./heiti.ttf"); // load the *.ttf font file as binary string
    // add the font to jsPDF
    pdf.addFileToVFS("MyFont.ttf", myFont.toString("binary"));
    pdf.addFont("MyFont.ttf", "MyFont", "normal");
    pdf.setFont("MyFont");
    // pdf.setFont('heiti')
    const perPageCount = row * col;
    let pageIndex = 0;
    const head = (_a = contents.shift()) !== null && _a !== void 0 ? _a : [];
    for (let i = 0; i < contents.length; i++) {
        const innerPageIndex = i % perPageCount;
        const pageNum = Math.floor(i / perPageCount);
        if (pageNum > pageIndex) {
            pdf.addPage();
            pageIndex = pageNum;
        }
        const labelPoint = calcPos(zero_point, label_size, gap, col, innerPageIndex);
        // const labelContents = contents[i].map(
        //   (v: any, j: number) => `${head[j]}： ${v}`,
        // );
        // drawOneLabel(pdf, label_size, labelPoint, labelContents, 2, withBorder);
        drawBagLabel(pdf, label_size, labelPoint, contents[i], 2, withBorder);
    }
    console.log(`共生成 ${pageIndex + 1} 页，${contents.length} 张标签`);
    // 保存PDF文档
    pdf.save(tryFilePath(filePath));
}
/**
 * 绘制标签内容，不同的配置这个函数要对应修改
 * @param pdf pdf对象
 * @param label 标签尺寸
 * @param point 标签左上角位置
 * @param content 内容
 * @param radius 圆角半径
 * @param withBorder 是否要边框
 * @returns
 */
function drawOneLabel(pdf, label, point, content, radius, withBorder = true) {
    const { w, h } = label;
    const { x, y } = point;
    if (withBorder) {
        pdf.setLineWidth(1);
        pdf.setDrawColor("#0000FF");
        pdf.roundedRect(x, y, w, h, radius, radius).fill();
    }
    drawCenterText(pdf, label, point, "存档文件", 32, -20);
    drawCenterText(pdf, label, point, content[1], 12, -10);
    drawLeftText(pdf, label, point, content[0], 10, 3, 45);
    drawLeftText(pdf, label, point, content[2], 10, 45, 45);
    return pdf;
}
/**
 * 绘制标签内容，不同的配置这个函数要对应修改
 * @param pdf pdf对象
 * @param label 标签尺寸
 * @param point 标签左上角位置
 * @param content 内容
 * @param radius 圆角半径
 * @param withBorder 是否要边框
 * @returns
 */
function drawBagLabel(pdf, label, point, content, radius, withBorder = true) {
    const { w, h } = label;
    const { x, y } = point;
    if (withBorder) {
        pdf.setLineWidth(1);
        pdf.setDrawColor("#ffc0cb");
        pdf.roundedRect(x, y, w, h, radius, radius).fill();
    }
    console.log("fd", label, point, content[1]);
    drawCenterText(pdf, label, point, content[1], 32, -15);
    drawCenterText(pdf, label, point, content[2], 22, 5);
    drawCenterText(pdf, label, point, content[3], 22, 15);
    // drawLeftText(pdf, label, point, content[2], 22, 45, 45);
    return pdf;
}
function calcPos(zeroPoint, label, gap, col, index) {
    const { w, h } = label;
    const { x: startX, y: startY } = zeroPoint;
    const posX = startX + (index % col) * (w + gap.x);
    const posY = startY + Math.floor(index / col) * (h + gap.y);
    return { x: posX, y: posY };
}
/**
 * 计算纸张上最大行数列数
 * @param paper 纸张尺寸
 * @param label 标签尺寸
 * @param gap 间隔尺寸
 * @returns 行数列数
 */
function calcMaxRowCol(paper, label, gap, zeroPoint) {
    const maxCol = Math.floor((paper.w - zeroPoint.x + gap.x) / (label.w + gap.x));
    const maxRow = Math.floor((paper.h - zeroPoint.y + gap.y) / (label.h + gap.y));
    return { row: maxRow, col: maxCol };
}
/**
 * 展示配置
 * @param paper 纸张尺寸
 * @param label 标签尺寸
 * @param gap 间隔尺寸
 * @param zeroPoint 原点位置
 */
function showProfile(profile) {
    const { paper_size, label_size, gap, zero_point } = profile;
    const { row, col } = calcMaxRowCol(paper_size, label_size, gap, zero_point);
    console.log(`参数（mm）：
纸张宽高：${paper_size.w}, ${paper_size.h}
标签宽高：${label_size.w}, ${label_size.h}
标签间隔：${gap.x}, ${gap.y}
标签原点：${zero_point.x}, ${zero_point.y}
一张纸上标签行列：${row} 行 ${col} 列
一张纸上标签数量：${row * col} 张
`);
}
/**
 * 绘制居中文本
 *
 * @param pdf 文档
 * @param label 标签宽高
 * @param labelPoint 标签坐标
 * @param text 文本
 * @param fontSize 字号
 * @param offsetY Y偏移量
 */
function drawCenterText(pdf, label, labelPoint, text, fontSize, offsetY = 0) {
    pdf.setFontSize(fontSize);
    const dimension = pdf.getTextDimensions(text);
    const { x, y } = calcCenterTextLeftPoint(labelPoint, label, dimension, offsetY);
    pdf.text(text, x, y);
}
function drawLeftText(pdf, label, labelPoint, text, fontSize, offsetX = 0, offsetY = 0) {
    pdf.setFontSize(fontSize);
    const dimension = pdf.getTextDimensions(text);
    if (offsetX + dimension.w > label.w) {
        console.error(`${text} 宽度超出尺寸范围 ${label.w}`);
    }
    if (offsetY + dimension.h > label.h) {
        console.log("gg", offsetY, dimension.h, label.h);
        console.error(`${text} 高度超出尺寸范围 ${label.h}`);
    }
    const { x, y } = calcLeftTextPoint(labelPoint, offsetX, offsetY);
    const opt = {
        align: "left",
        maxWidth: label.w,
    };
    pdf.text(text, x, y, opt);
}
function calcLeftTextPoint(point, offsetX = 0, offsetY = 0) {
    const { x, y } = point;
    return {
        x: x + offsetX,
        y: y + offsetY,
    };
}
function calcCenterTextLeftPoint(point, label, dimension, offsetY = 0) {
    const { x, y } = point;
    const { w: labelW, h: labelH } = label;
    const { w: fontW, h: fontH } = dimension;
    return {
        x: x + (labelW / 2 - fontW / 2),
        y: y + (labelH / 2 + fontH / 2 - 1) + offsetY,
    };
}
function tryFilePath(val) {
    let newPath = val;
    const dir = path.dirname(val);
    const ext = path.extname(val);
    const base = path.basename(val, ext);
    let i = 1;
    while (fs.existsSync(newPath)) {
        newPath = path.join(dir, `${base}(${i})${ext}`);
        i++;
    }
    return newPath;
}
